// 步进格式化
function roundStep (qty, stepSize) {
  stepSize = '' + stepSize
  // Integers do not require rounding
  if (Number.isInteger(qty)) return qty
  const qtyString = parseFloat(qty).toFixed(16)
  const desiredDecimals = Math.max(stepSize.indexOf('1') - 1, 0)
  const decimalIndex = qtyString.indexOf('.')
  return parseFloat(qtyString.slice(0, decimalIndex + desiredDecimals + 1))
}

function formatPrice (price, btbItem) {
  return roundStep(price, btbItem.tick_size || 0)
}

// 格式化币的数量
function formatVal (available, btbItem) {
  // 数量太少
  if (available < btbItem.min_qty) {
    return 0
  }
  // 金额太小
  if ((available * btbItem.close) < (btbItem.min_notional * 1.01)) {
    return 0
  }
  return roundStep(available, btbItem.step_size || 0)
}

function formatValPing (available, btbItem) {
  // 数量太少
  if (available < btbItem.min_qty) {
    return 0
  }
  // 金额太小
  if ((Math.abs(btbItem.usdt)) < (btbItem.min_notional * 1.01)) {
    return 0
  }
  return roundStep(available, btbItem.step_size || 0)
}

/**
 * @param available 卖出份额
 * @param btbItem 详情
 * @param price 目前价格
 * @returns {*}
 */
function formatMinSell (wantUsdt, btbItem) {
  let quantity = wantUsdt / btbItem.close
  // 数量太少
  if (quantity < btbItem.min_qty) {
    return 0
  }
  // 金额太小
  if (wantUsdt < (btbItem.min_notional * 1.01)) {
    return 0
  }
  return roundStep(quantity, btbItem.step_size || 0)
}

/**
 * @param buyUsdt 购买数量
 * @param btbItem 详情
 * @param price 价格
 * @returns {*}
 */
function formatMinBuy (buyUsdt, btbItem) {
  let quantity = buyUsdt / btbItem.close
  // 数量太少
  if (quantity < btbItem.min_qty) {
    return false
  }
  // 金额太小
  if ((buyUsdt) < (btbItem.min_notional * 1.01)) {
    return false
  }
  return roundStep(quantity, btbItem.step_size || 0)
}

function getQuantity (asRes, btbItem, btbIndexConfig, leverage) {
  // 按保证金计算
  const itemUsdtAll = (btbItem.proportion / btbIndexConfig.proportionAll) * btbIndexConfig.balance.POSITION
  // 买入
  if (asRes.buy) {
    let rate = asRes.buyRate || 1
    // 使用保证金
    let wantUsdt = itemUsdtAll * rate
    // 已经有多单持仓
    if (btbItem.usdt >= 0) {
      // 减去已有保证金
      wantUsdt = wantUsdt - btbItem.initialMargin
    }
    if (wantUsdt < 0) {
      wantUsdt = 0
    }
    // 需要增加的仓位超出剩余usdt
    if (wantUsdt >= (btbIndexConfig.balance.USDT) * 0.95) {
      wantUsdt = (btbIndexConfig.balance.USDT) * 0.95
    }
    // 计算上杠杆
    wantUsdt = (leverage || 1) * wantUsdt
    // 把空单加上
    if (btbItem.usdt < 0) {
      wantUsdt = wantUsdt - btbItem.usdt
    }
    return formatMinBuy(wantUsdt, btbItem)
  } else if (asRes.sell) {
    // 卖出
    let rate = asRes.sellRate || 1
    // 使用保证金
    let wantUsdt = itemUsdtAll * rate
    // 已经有的空单
    if (btbItem.usdt < 0) {
      // 减去已有保证金
      wantUsdt = wantUsdt - btbItem.initialMargin
    }
    if (wantUsdt < 0) {
      wantUsdt = 0
    }
    // 需要增加的仓位超出剩余usdt
    if (wantUsdt >= (btbIndexConfig.balance.USDT) * 0.95) {
      wantUsdt = (btbIndexConfig.balance.USDT) * 0.95
    }
    // 计算上杠杆
    wantUsdt = (leverage || 1) * wantUsdt
    // 把多单加上
    if (btbItem.usdt >= 0) {
      wantUsdt = wantUsdt + btbItem.usdt
    }
    return formatMinSell(wantUsdt, btbItem)
  } else if (asRes.pingKong) {
    // 平空，直接算持仓的数量
    let val = 0 - btbItem.balance
    return formatVal(val, btbItem)
  } else if (asRes.pingDuo) {
    // 平多，直接算持仓的数量
    let val = btbItem.balance - 0
    return formatVal(val, btbItem)
  }
}

function getQuantityV2 (btbItem, info) {
  // 按保证金计算
  const itemUsdtAll = info.standardInitialMargin
  // 买入
  if (info.buy) {
    let rate = info.buyRate || 1
    // 使用保证金
    let wantUsdt = itemUsdtAll * rate
    // 已经有多单持仓
    if (btbItem.usdt >= 0) {
      let af = wantUsdt + info.initialMargin
      if (af > itemUsdtAll) {
        af = itemUsdtAll
      }
      wantUsdt = af - info.initialMargin
    }
    if (wantUsdt < 0) {
      wantUsdt = 0
    }
    // 需要增加的仓位超出剩余usdt
    if (wantUsdt >= (info.availableBalance) * 0.95) {
      wantUsdt = (info.availableBalance) * 0.95
    }
    // 计算上杠杆
    wantUsdt = (info.leverage || 1) * wantUsdt
    // 把空单加上
    if (btbItem.usdt < 0) {
      wantUsdt = wantUsdt - btbItem.usdt
    }
    return formatMinBuy(wantUsdt, btbItem)
  } else if (info.sell) {
    // 卖出
    let rate = info.sellRate || 1
    // 使用保证金
    let wantUsdt = itemUsdtAll * rate
    // 已经有的空单
    if (btbItem.usdt < 0) {
      let af = wantUsdt + info.initialMargin
      if (af > itemUsdtAll) {
        af = itemUsdtAll
      }
      wantUsdt = af - info.initialMargin
    }
    if (wantUsdt < 0) {
      wantUsdt = 0
    }
    // 需要增加的仓位超出剩余usdt
    if (wantUsdt >= (info.availableBalance) * 0.95) {
      wantUsdt = (info.availableBalance) * 0.95
    }
    // 计算上杠杆
    wantUsdt = (info.leverage || 1) * wantUsdt
    // 把多单加上
    if (btbItem.usdt >= 0) {
      wantUsdt = wantUsdt + btbItem.usdt
    }
    return formatMinSell(wantUsdt, btbItem)
  } else if (info.pingKong) {
    // 平空，直接算持仓的数量
    let val = 0 - info.positionAmt
    let pingKongNum = formatVal((val * (info.pingKongRate || 1)), btbItem)
    if (!pingKongNum) {
      pingKongNum = formatVal(val, btbItem)
    }
    return pingKongNum
  } else if (info.pingDuo) {
    // 平多，直接算持仓的数量
    let val = info.positionAmt - 0
    let pingDuoNum = formatVal((val * (info.pingDuoRate || 1)), btbItem)
    if (!pingDuoNum) {
      pingDuoNum = formatVal(val, btbItem)
    }
    return pingDuoNum
  }
}

module.exports = {
  getQuantity,
  getQuantityV2,
  formatVal,
  formatValPing,
  formatPrice
}
